Scenario
소스코드를 수정할 수 없는 경우, 각 계층마다 멤버 함수를 추가하는 것은 불가능하다.
이와 같은 경우에 방문자 패턴을 사용한다.
(방문자 패턴은 인터프리터 패턴과 나란히 사용되는 경우가 많다)
수학 수식을 파싱하는 경우
struct Expression{
};
struct DoubleExpression: Expression{
double value;
explicit DoubleExpression(const double value): value(value) {}
};
struct AdditionExpression: Expression{
Expression *left, *right;
AdditionExpression(Expression* const left, Expression* const right): left(left), right(right) {}
~AdditionExpression(){
delete left; delete right;
}
};
위와 같은 형태의 객체의 계층이 주어져 있을 때, 새로운 동작(메서드)를 추가해야 하는 경우
위에서 Expression 객체 left와 right를 AdditionExpression 클래스에서 할당 해제한다.
이는 OCP를 위배한다
침습적 방문자
struct Expression{
virtual void print(ostringstream& oss)=0;
};
만일 소스 코드를 변경할 수 있는 경우, 위와 같이 인터페이스를 수정해서 하위 모든 클래스를 수정할 수 있다.
struct AdditionExpression: Expression{
Expression *left, *right;
void print(ostringstream& oss) override {
oss<<"(";
left->print(oss);
oss<<"+";
right->print(oss);
oss<<")";
}
};
auto e=new AdditionExpression{
new DoubleExpression{1},
new AdditionExpression{
new DoubleExpression{2},
new DoubleExpression{3}
}
};
ostringstream oss;
e->print(oss);
cout<<oss.str()<<endl;